#ifndef LONGKEY_COMMON_EVENT_LOGGER_H_
#define LONGKEY_COMMON_EVENT_LOGGER_H_

#include <atlstr.h>
#include "../base/basictypes.h"

void LogEventHelper(WORD type, DWORD id, size_t count, const TCHAR** strings,
					const TCHAR* ctx);

// Logs an event to the Application log
inline void LogEvent(WORD type, DWORD id) {
	LogEventHelper(type, id, 0, NULL, NULL);
}

inline void LogEvent(WORD type, DWORD id, const TCHAR* s) {
	const TCHAR* strings[] = {s};
	LogEventHelper(type, id, arraysize(strings), strings, NULL);
}

inline void LogEvent(WORD type, DWORD id, const TCHAR* s1, const TCHAR* s2) {
	const TCHAR* strings[] = {s1, s2};
	LogEventHelper(type, id, arraysize(strings), strings, NULL);
}

inline void LogEvent(WORD type, DWORD id, const TCHAR* s1, const TCHAR* s2,
					 const TCHAR* s3)
{
	const TCHAR* strings[] = {s1, s2, s3};
	LogEventHelper(type, id, arraysize(strings), strings, NULL);
}

// Logs an event to the Application log with a context string.
inline void LogEventContext(WORD type, DWORD id, const TCHAR* ctx) {
	LogEventHelper(type, id, 0, NULL, ctx);
}

inline void LogEventContext(WORD type, DWORD id, const TCHAR* s,
							const TCHAR* ctx)
{
	const TCHAR* strings[] = {s};
	LogEventHelper(type, id, arraysize(strings), strings, ctx);
}

inline void LogEventContext(WORD type, DWORD id, const TCHAR* s1,
							const TCHAR* s2, const TCHAR* ctx)
{
	const TCHAR* strings[] = {s1, s2};
	LogEventHelper(type, id, arraysize(strings), strings, ctx);
}

inline void LogEventContext(WORD type, DWORD id, const TCHAR* s1,
							const TCHAR* s2, const TCHAR* s3,
							const TCHAR* ctx)
{
	const TCHAR* strings[] = {s1, s2, s3};
	LogEventHelper(type, id, arraysize(strings), strings, ctx);
}

class EventLogger {
public:
	// Creates an event source for the "Application" log so that EventViewer can
	// map event identifier codes to message strings.
	static HRESULT AddEventSource(
		const TCHAR* src_name,       // Event source name.
		const TCHAR* msg_dll_path);  // Path for message DLL.

	static HRESULT RemoveEventSource(
		const TCHAR* src_name);      // Event source name.

	// Writes an entry at the end of event log that contains the source name.
	static HRESULT ReportEvent(
		const TCHAR* src_name,       // Event source name.
		WORD type,                   // Type of the event to be logged.
		WORD category,               // Event category.
		DWORD id,                    // Event identifier.
		WORD count,                  // Count of insert strings.
		const TCHAR** strings,       // Insert strings.
		size_t buf_size,             // Size of binary data to append.
		void* buffer);               // Buffer containing the binary data.

	// Reads the topmost event log record.
	static HRESULT ReadLastEvent(const TCHAR* src_name, EVENTLOGRECORD* rec);

	// Default name for the event source.
	static const TCHAR* const kSourceName;

	// Default event category.
	static const WORD kDefaultCategory = 0;
};

class LongkeyPCAgentLogEvent {
public:
	LongkeyPCAgentLogEvent(int type, int id, bool is_machine)
		: type_(type),
		id_(id),
		is_machine_(is_machine) {}
	LongkeyPCAgentLogEvent() : type_(0), id_(0), is_machine_(false) {}
	~LongkeyPCAgentLogEvent() {}
	void WriteEvent();
	void set_event_desc(const CString& desc) { event_desc_ = desc; }
	void set_event_text(const CString& text) { event_text_ = text; }

private:
	CString event_desc_;
	CString event_text_;
	int type_;
	int id_;
	bool is_machine_;

	DISALLOW_EVIL_CONSTRUCTORS(LongkeyPCAgentLogEvent);
};

#endif	// LONGKEY_COMMON_EVENT_LOGGER_H_